require "behaviours/wander"
require "behaviours/chaseandattack"
require "behaviours/panic"
require "behaviours/leash"
require "behaviours/faceentity"
require "behaviours/doaction"
require "behaviours/standstill"

local MIN_FOLLOW_LEADER = 1
local MAX_FOLLOW_LEADER = 6
local TARGET_FOLLOW_LEADER = 3

local START_FACE_DIST = 6
local KEEP_FACE_DIST = 8

local LEASH_RETURN_DIST = 15
local LEASH_MAX_DIST = 40

local SIT_BOY_DIST = 15

local SEE_DIST = 6

local GHoundBrain =
	Class(
	Brain,
	function(self, inst)
		Brain._ctor(self, inst)
	end
)

local function EatFoodAction(inst)
	local target =
		FindEntity(
		inst,
		SEE_DIST,
		function(item)
			return inst.components.fueled:GetPercent() < .4 and item.prefab == "ice" and item:IsOnValidGround()
		end
	)
	if target then
		return BufferedAction(inst, target, ACTIONS.EAT)
	end
end

local function GetLeader(inst)
	return inst.components.follower and inst.components.follower.leader
end

local function GetHome(inst)
	return inst.components.homeseeker and inst.components.homeseeker.home
end

local function GetHomePos(inst)
	local home = GetHome(inst)
	return home and home:GetPosition()
end

local function GetNoLeaderLeashPos(inst)
	if GetLeader(inst) then
		return nil
	end
	return GetHomePos(inst)
end

local function GetFaceTargetFn(inst)
	local target = GetClosestInstWithTag("player", inst, START_FACE_DIST)
	if target and not target:HasTag("notarget") then
		return target
	end
end

local function KeepFaceTargetFn(inst, target)
	return inst:IsNear(target, KEEP_FACE_DIST) and not target:HasTag("notarget")
end

local function ShouldStandStill(inst)
	return inst:HasTag("pet_hound") and not GetClock():IsDay() and not GetLeader(inst) and
		not inst.components.combat.target and
		inst:IsNear(GetHome(inst), SIT_BOY_DIST)
end

function GHoundBrain:OnStart()
	local root =
		PriorityNode(
		{
			ChaseAndAttack(self.inst, 10),
			WhileNode(
				function()
					return self.inst.components.health.takingfiredamage
				end,
				"OnFire",
				Panic(self.inst)
			),
			Leash(self.inst, GetNoLeaderLeashPos, LEASH_MAX_DIST, LEASH_RETURN_DIST),
			DoAction(self.inst, EatFoodAction, "eat food", true),
			Follow(self.inst, GetLeader, MIN_FOLLOW_LEADER, TARGET_FOLLOW_LEADER, MAX_FOLLOW_LEADER),
			FaceEntity(self.inst, GetLeader, GetLeader),
			StandStill(self.inst, ShouldStandStill),
			IfNode(
				function()
					return GetLeader(self.inst)
				end,
				"has leader",
				FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn)
			)
		},
		.5
	)

	self.bt = BT(self.inst, root)
end

return GHoundBrain
